package com.haiwei.poi.word.common;

import org.apache.poi.xwpf.usermodel.XWPFDocument;

import java.io.*;
import java.net.URL;

/**
 * 文档对象生成器
 *
 * @date: 2022-06-24
 * @version: 1.0
 * @author: karry@haiwei.com
 */
public class HaiweiDocumentGenerator {
    
    /**
     * 文件前缀
     */
    private static final String TEMP_FILE_PREFIX = "haiwei.word.template.temp.";
    /**
     * 模板文件后缀
     */
    private static final String TEMP_FILE_SUFFIX = "docs";
    
    /**
     * 生成二进制字符串
     * @param document
     * @return
     * @throws IOException
     */
    public static byte[] toBytes(XWPFDocument document) throws IOException {
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        try {
            document.write(outputStream);
            return outputStream.toByteArray();
        } finally {
            outputStream.close();
        }
    }
    
    public static File toFile(XWPFDocument document) throws IOException {
        return toFile(document,null);
    }
    
    /**
     * 生成本地文件
     * @param document
     * @return
     * @throws IOException
     */
    public static File toFile(XWPFDocument document,File tempFile) throws IOException {
        // 创建一个临时文件
        if(tempFile == null){
            tempFile = HaiweiWeakTempFile.createTempFile(TEMP_FILE_PREFIX,TEMP_FILE_SUFFIX);
        }
        FileOutputStream fos = null;
        OutputStream buffer = null;
        try {
            fos = new FileOutputStream(tempFile);
            buffer = new BufferedOutputStream(fos);
    
            buffer.write(toBytes(document));
            
        }finally {
            try {
                if(buffer != null) {
                    buffer.flush();
                    buffer.close();
                }
            }catch (Exception e){}
            try {
                if(fos != null){
                    fos.close();
                }
            }catch (Exception e){}
        }
        
        return tempFile;
    }
    
    /**
     * 生成文件
     * @param inputStream
     * @return
     * @throws IOException
     */
    public static File crateTempFile(InputStream inputStream) throws IOException {
        // 创建一个临时文件
        File tempFile = HaiweiWeakTempFile.createTempFile(TEMP_FILE_PREFIX,TEMP_FILE_SUFFIX);
        // 从流中读取数据到文件
        FileOutputStream fos = null;
        OutputStream buffer = null;
        try {
            fos = new FileOutputStream(tempFile);
            buffer = new BufferedOutputStream(fos);
            byte[] data = new byte[1024 * 20];
            int ch = 0;
            while((ch = inputStream.read(data)) != -1){
                buffer.write(data,0 ,ch);
            }
        }finally {
            try {
                if(buffer != null) {
                    buffer.flush();
                    buffer.close();
                }
            }catch (Exception e){}
            try {
                if(fos != null){
                    fos.close();
                }
            }catch (Exception e){}
        }
        return tempFile;
    }
    
    /**
     * 读取URL对应的模板文件
     * @param url
     * @return
     * @throws IOException
     */
    public static XWPFDocument build(URL url) throws IOException {
        return build(url.openConnection().getInputStream());
    }
    
    /**
     * 生成XWPFDocument对象
     * @param inputStream 文件流
     * @return
     * @throws IOException
     */
    public static XWPFDocument build(InputStream inputStream) throws IOException {
        // 缓存文件到本地
        final File tempFile = crateTempFile(inputStream);
        // 生成Document对象
        return build(tempFile);
    }
    
    /**
     * 生成XWPFDocument对象
     * @param localFile 本地文件
     * @return
     * @throws IOException
     */
    public static XWPFDocument build(File localFile) throws IOException {
        // 生成Document对象
        return new XWPFDocument(new FileInputStream(localFile));
    }
}
